﻿using AntUnion.FrameWork.Model.Models;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace AntUnion.FrameWork.Util
{
    /// <summary>
    /// 缓存操作类
    /// </summary>
    public class MemoryCacheUtil
    {
        private IMemoryCache cache;
        private static readonly object lockobj = new object();
        private TimeSpan ts = TimeSpan.FromDays(1);
        public MemoryCacheUtil()
        {
        }

        /// <summary>
        /// 获取MemoryCache管理对象
        /// </summary>
        /// <returns></returns>
        public IMemoryCache MemoryCache
        {
            get
            {
                lock (lockobj)//控制多线程的并发问题
                {
                    if (cache == null)
                    {
                        cache = new MemoryCache(new MemoryCacheOptions());
                    }
                }
                return cache;
            }
        }

        #region 新增缓存
       
        public void Set(object key , object value)
        {
            MemoryCache.Set(key, value);
        }

        public void Set(object key, object value, TimeSpan absoluteExpirationRelativeToNow)
        {
            MemoryCache.Set(key, value, absoluteExpirationRelativeToNow);
        }

        #endregion

        #region 获取缓存

        public string GetString(string cacheKey)
        {
            var cache = MemoryCache;
            var cacheData = cache.Get(cacheKey);
            if (cacheData != null)
            {
                return cacheData.ToString();
            }
            else
            {
                return "";
            }
        }

        public T Get<T>(string cacheKey,T data)
        {
            T t;
            var cache = MemoryCache;
            var cacheData = cache.Get(cacheKey);
            if (cacheData == null)
            {
                return cache.Set(cacheKey, data );
            }
            else
            {
                t = (T)cacheData;
            }
            return t;
        }

        /// <summary>
        /// 获取缓存中的集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public List<T> GetCacheList<T>(string cacheKey, IEnumerable<T> data)
        {
            List<T> list;
            var cache = MemoryCache;
            var cacheData = cache.Get(cacheKey);
            if (cacheData == null)
            {
                list = data.ToList();
                //将验证结果添加到缓存
                cache.Set(cacheKey, list, ts);
            }
            else
            {
                list = cacheData as List<T>;
            }
            return list;
        }

        /// <summary>
        /// 获取缓存中的字典
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public Dictionary<object, object> GetCacheDic(string cacheKey, IEnumerable<CacheDict> data)
        {
            Dictionary<object, object> dict;
            var cache = MemoryCache;
            var cacheData = cache.Get(cacheKey);
            if (cacheData == null)
            {
                dict = data.ToDictionary(k => k.Key, k => k.Value);
                //将验证结果添加到缓存
                cache.Set(cacheKey, dict, ts);
            }
            else
            {
                dict = cacheData as Dictionary<object, object>;
            }
            return dict;
        }

        /// <summary>
        /// 获取通过Key获取缓存中的对应值
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public object GetValueByKey(string cacheKey, object key, IEnumerable<CacheDict> data)
        {
            Dictionary<object, object> dict = GetCacheDic(cacheKey, data);
            return dict.ContainsKey(key) ? dict[key] : null;
        }

        #endregion

        #region 更新缓存

        /// <summary>
        /// 更新缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public List<T> UpdateCache<T>(string cacheKey, IEnumerable<T> data)
        {
            MemoryCache.Remove(cacheKey);
            return GetCacheList(cacheKey, data);
        }

        /// <summary>
        /// 更新缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public Dictionary<object, object> UpdateCache(string cacheKey, IEnumerable<CacheDict> data)
        {
            MemoryCache.Remove(cacheKey);
            return GetCacheDic(cacheKey, data);
        }

        #endregion

        #region 移除缓存

        /// <summary>
        /// 移除对应缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        public void Remove(string cacheKey)
        {
            MemoryCache.Remove(cacheKey);
        }

        /// <summary>
        /// 清楚整个缓存
        /// </summary>
        public void Remove()
        {
            cache.Dispose();
        }

        #endregion
    }

    /// <summary>
    /// 存储缓存键值对
    /// </summary>
    public class CacheDict
    {
        public object Key { get; set; }
        public object Value { get; set; }
    }
}
